﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "framework.h"
#include "detours.h"
#include "stdio.h"
#include "windows.h"
#include <iostream>

#pragma comment(lib,"detours.lib")

using namespace std;

SYSTEMTIME st;

//定义和引入需要Hook的函数，和替换的函数
static int (WINAPI* OldMessageBoxA)(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType) = MessageBoxA;
static int (WINAPI* OldMessageBoxW)(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType) = MessageBoxW;

extern "C" __declspec(dllexport)int WINAPI NewMessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
{
    printf("\n\n*************************************\n");
    printf("MessageBoxA Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    printf("*************************************\n\n");
    return OldMessageBoxA(NULL, "new MessageBoxA", "Hooked", MB_OK);
}

extern "C" __declspec(dllexport)int WINAPI NewMessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
{
    printf("\n\n*************************************\n");
    printf("MessageBoxW Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    printf("*************************************\n\n");
    return OldMessageBoxW(NULL, L"new MessageBoxW", L"Hooked", MB_OK);
}

//文件操作 File_operation
//文件创建 CreateFile
static HANDLE(WINAPI* OldCreateFile)(
    LPCTSTR lpFileName,                                 //文件名
    DWORD dwDesiredAccess,                             //访问模式
    DWORD dwShareMode,                                 //共享模式
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,        //安全属性（也即销毁方式）
    DWORD dwCreationDisposition,                       //how to create
    DWORD dwFlagsAndAttributes,                        //文件属性
    HANDLE hTemplateFile                               //模板文件句柄
    ) = CreateFile;

extern "C" __declspec(dllexport)HANDLE WINAPI NewCreateFile(
    LPCTSTR lpFileName,                                 //文件名
    DWORD dwDesiredAccess,                             //访问模式
    DWORD dwShareMode,                                 //共享模式
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,        //安全属性（也即销毁方式）
    DWORD dwCreationDisposition,                       //how to create
    DWORD dwFlagsAndAttributes,                        //文件属性
    HANDLE hTemplateFile                               //模板文件句柄
)
{
    printf("\n\n*************************************\n");
    printf("CreateFile Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    int num = WideCharToMultiByte(CP_OEMCP, NULL, lpFileName, -1, NULL, 0, NULL, FALSE);
    char* pchar = new char[num];
    WideCharToMultiByte(CP_OEMCP, NULL, lpFileName, -1, pchar, num, NULL, FALSE);

    cout << "lpFileName : " << pchar << endl;
    cout << "dwDesiredAccess : 0x" << hex << dwDesiredAccess << endl;
    cout << "dwShareMode : 0x" << hex << dwShareMode << endl;
    cout << "lpSecurityAttributes : 0x" << hex << lpSecurityAttributes << endl;
    cout << "dwCreationDisposition : 0x" << hex << dwCreationDisposition << endl;
    cout << "dwFlagsAndAttributes : 0x" << hex << dwFlagsAndAttributes << endl;
    cout << "hTemplateFile : 0x" << hex << hTemplateFile << endl;

    printf("*************************************\n\n");
    return OldCreateFile(lpFileName, dwDesiredAccess, dwDesiredAccess, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}

//文件关闭 CloseFile

//读文件 ReadFile
static BOOL(WINAPI* OldReadFile)(
    __in   HANDLE hFile,                   // 文件句柄
    __out  LPVOID lpBuffer,                // 接收数据用的 buffer
    __in   DWORD nNumberOfBytesToRead,     // 要读取的字节数
    __out  LPDWORD lpNumberOfBytesRead,    // 实际读取到的字节数
    __in   LPOVERLAPPED lpOverlapped       // OVERLAPPED 结构，一般设定为 NULL 
    ) = ReadFile;

extern "C" __declspec(dllexport)HANDLE WINAPI NewReadFile(
    __in   HANDLE hFile,                   // 文件句柄
    __out  LPVOID lpBuffer,                // 接收数据用的 buffer
    __in   DWORD nNumberOfBytesToRead,     // 要读取的字节数
    __out  LPDWORD lpNumberOfBytesRead,    // 实际读取到的字节数
    __in   LPOVERLAPPED lpOverlapped       // OVERLAPPED 结构，一般设定为 NULL 
)
{
    printf("\n\n*************************************\n");
    printf("ReadFile Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    //待打印的内容
}

//写文件
static BOOL(WINAPI* OldWriteFile)(
    __in          HANDLE hFile,                   // 文件句柄
    __in          LPCVOID lpBuffer,               // 要写入的数据
    __in          DWORD nNumberOfBytesToWrite,    // 要写入的字节数
    __out         LPDWORD lpNumberOfBytesWritten, // 实际写入的字节数
    __in          LPOVERLAPPED lpOverlapped       // OVERLAPPED 结构，一般设定为 NULL
    ) = WriteFile;

extern "C" __declspec(dllexport)HANDLE WINAPI NewWriteFile(
    __in          HANDLE hFile,                   // 文件句柄
    __in          LPCVOID lpBuffer,               // 要写入的数据
    __in          DWORD nNumberOfBytesToWrite,    // 要写入的字节数
    __out         LPDWORD lpNumberOfBytesWritten, // 实际写入的字节数
    __in          LPOVERLAPPED lpOverlapped       // OVERLAPPED 结构，一般设定为 NULL
)
{
    printf("\n\n*************************************\n");
    printf("WriteFile Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    //待打印的内容
};


//堆操作 Heap_operation
//堆创建 HeapCreate
static HANDLE(WINAPI* oldHeapCreate)(DWORD fIOoption, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) = HeapCreate;

extern "C" __declspec(dllexport)HANDLE WINAPI NewHeapCreate(DWORD fIOoption, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
{
    HANDLE hHeap = oldHeapCreate(fIOoption, dwInitialSize, dwMaximumSize);
    printf("\n\n*************************************\n");
    printf("HeapCreate Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    cout << "fIOoptions : " << fIOoption << endl;
    cout << "dwInitialSize : " << dwInitialSize << endl;
    cout << "dwMaximumSize : " << dwMaximumSize << endl;
    cout << "hHeap : " << hHeap << endl;
    printf("*************************************\n\n");
    return hHeap;
}

//堆释放 HeapDestroy
static BOOL(WINAPI* oldHeapDestroy)(HANDLE) = HeapDestroy;

extern "C" __declspec(dllexport)BOOL WINAPI NewHeapDestroy(HANDLE hHeap)
{
    printf("\n\n*************************************\n");
    printf("HeapDestroy Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    cout << "hHeap : " << hHeap << endl;
    printf("*************************************\n\n");
    return oldHeapDestroy(hHeap);
}

//注册表操作 Reg_operation
//读注册表 RegGetValueA
static LSTATUS(WINAPI* OldRegQueryValueExA)(
    HKEY    hKey,					//已打开的键的句柄
    LPCSTR  lpValueName,			//键值名称，如果为NULL或“”,则设置键值名为“默认”的项
    LPDWORD lpReserved,			    //保留，必须为0
    LPDWORD lpType,				    //【出参】，返回数据类型
    LPBYTE  lpData,				    //【出参】, 返回数据
    LPDWORD lpcbData				//【出参】, 返回数据长度
    ) = RegQueryValueExA;

extern "C" __declspec(dllexport)LSTATUS WINAPI NewRegQueryValueExA(
    HKEY    hkey,				//已打开的键的句柄，一般是根键
    LPCSTR  lpSubKey,			//hKey的子键路径
    LPCSTR  lpValue,			//键值项名称
    DWORD   dwFlags,			//对于返回键值类型的限制，如果不满足，函数会执行失败
    LPDWORD pdwType,			//【出参】 返回的数据类型
    PVOID   pvData,			    //【出参】, 返回数据
    LPDWORD pcbData			    //【出参】, 返回数据长度
)
{
    printf("\n\n*************************************\n");
    printf("RegQueryValueExA Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    //待打印的内容
};

//写注册表
static LSTATUS(WINAPI* OldRegSetValueExA)(
    HKEY       hKey,				//已打开的键的句柄
    LPCSTR     lpValueName,		    //键值名称，如果为NULL或“”,则设置键值名为“默认”的项
    DWORD      Reserved,			//保留，必须为0
    DWORD      dwType,			    //设置的键值数据类型
    const BYTE* lpData,			    //指向键值数据的指针
    DWORD      cbData				//设置的键值数据长度
    ) = RegSetValueExA;

extern "C" __declspec(dllexport)LSTATUS WINAPI NewRegSetValueExA(
    HKEY       hKey,				//已打开的键的句柄
    LPCSTR     lpValueName,		    //键值名称，如果为NULL或“”,则设置键值名为“默认”的项
    DWORD      Reserved,			//保留，必须为0
    DWORD      dwType,			    //设置的键值数据类型
    const BYTE * lpData,			    //指向键值数据的指针
    DWORD      cbData				//设置的键值数据长度
)
{
    printf("\n\n*************************************\n");
    printf("RegSetValueExA Hooked\n");
    GetLocalTime(&st);
    printf("DLL日志输出：%d-%d-%d %02d: %02d: %03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    //待打印的内容
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        DisableThreadLibraryCalls(hModule);
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)OldMessageBoxW, NewMessageBoxW);
        DetourAttach(&(PVOID&)OldMessageBoxA, NewMessageBoxA);
        DetourAttach(&(PVOID&)OldCreateFile, NewCreateFile);
        DetourAttach(&(PVOID&)oldHeapCreate, NewHeapCreate);
        DetourAttach(&(PVOID&)oldHeapDestroy, NewHeapDestroy);
        DetourTransactionCommit();
    }
    break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)OldMessageBoxW, NewMessageBoxW);
        DetourAttach(&(PVOID&)OldMessageBoxA, NewMessageBoxA);
        DetourAttach(&(PVOID&)OldCreateFile, NewCreateFile);
        DetourAttach(&(PVOID&)oldHeapCreate, NewHeapCreate);
        DetourAttach(&(PVOID&)oldHeapDestroy, NewHeapDestroy);
        DetourTransactionCommit();
        break;
    }
    return TRUE;
}

